package com.zxd.interview.jmm;

/**
 * 可见性问题
 * 可见性问题是由于本地内存和主存数据不一致导致
 *
 *
 * 为什么只需要修改b即可保证程序正常？
 * b设置为volatile之后，后续的所有读取必然可以看到b的所有操作
 * 意味着 b = a，这个赋值操作肯定也是看得到的
 * 关键 b 的任何数据操作都可以被看到，这里引申到 happens-before原则
 *
 *
 */
public class Visibility {

    int a = 1;

    // 修复问题只需要给b变量加上 volatile

//    int b = 2;
    volatile int b = 2;

    private void change(){
        a = 3;
        b = a;
    }

    private void print(){
        System.out.println("b ="+ b+ " a = "+ a);
    }

    public static void main(String[] args) {
        while(true){
            Visibility visibility = new Visibility();
            new Thread(()->{
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                visibility.change();
            }).start();

            new Thread(()->{
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                visibility.print();
            }).start();
        }
    }/**
     b =2 a = 1
     b =3 a = 3
     b =3 a = 1

     情况汇总：
     第一种情况：
     b =2 a = 1
     print() 线程比 change() 线程先执行

     第二种情况
     b =3 a = 3
     print() 线程比 change() 线程后执行

     第三种情况
     b =3 a = 1
     print() 发生了可见性问题


     */
}
